package com.traffic.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.traffic.constant.Status;

import com.traffic.entity.Rank;
import com.traffic.entity.User;
import com.traffic.entity.UserInfo;
import com.traffic.exception.BaseException;
import com.traffic.service.RankService;
import com.traffic.util.CalculateUtil;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.traffic.entity.Drivedata;
import com.traffic.mapper.DrivedataMapper;
import com.traffic.service.DrivedataService;

@Service
public class DrivedataServiceImpl extends ServiceImpl<DrivedataMapper, Drivedata> implements DrivedataService{

    @Autowired
    private DrivedataMapper drivedataMapper;

    @Autowired
    private RankService rankService;

    @Autowired
    private CalculateUtil calculateUtil;

    @Autowired
    private UserInfoServiceImpl userInfoService;

    @Override
    public int insertDriveData(Map<String, Object> Param) {

        String param[] = new String[]{"trail_id","score","average_speed","max_speed",
                "average_acceleration","max_acceleration","mileage","time","stationarity","max_nacceleration"};

        List<String> paramList = CollUtil.newArrayList(param);
        if (!paramList.containsAll(CollUtil.newArrayList(Param.keySet().toArray()))) {
            throw new BaseException(Status.PARAM_ERROR);
        }

        Drivedata dri = new Drivedata();
        BeanUtil.copyProperties(Param, dri, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));


        int result = drivedataMapper.insert(dri);

        return dri.getId();
    }

    @Override
    public int updateDriveData(Map<String, Object> Param) {
        String param[] = new String[]{"id","trail_id","score","average_speed","max_speed",
                "average_acceleration","max_acceleration","max_nacceleration","mileage","time","stationarity"};

 //       List<String> paramList = CollUtil.newArrayList(param);

        QueryWrapper<Drivedata> wrapper = new QueryWrapper<>();

        Drivedata dri = drivedataMapper.selectOne(wrapper.eq("trail_id",Param.get("trail_id")));
 //       BeanUtil.copyProperties(Param, dri, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));

        DecimalFormat df = new DecimalFormat("###.#####");

        //dri.setId(Integer.parseInt(Param.get("id").toString()));
        //dri.setTrailId(Long.parseLong(Param.get("trail_id").toString()));
        dri.setScore(Math.abs(Double.parseDouble(df.format(Double.parseDouble(Param.get("score").toString())))));
        dri.setAverageSpeed(Math.abs(Double.parseDouble(df.format(Double.parseDouble(Param.get("average_speed").toString())))));
        dri.setMaxSpeed(Math.abs(Double.parseDouble(df.format(Double.parseDouble(Param.get("max_speed").toString())))));
        dri.setAverageAcceleration(Math.abs(Double.parseDouble(df.format(Double.parseDouble(Param.get("average_acceleration").toString())))));
        dri.setMaxAcceleration(Math.abs(Double.parseDouble(df.format(Double.parseDouble(Param.get("max_acceleration").toString())))));
        dri.setMaxNacceleration(Math.abs(Double.parseDouble(df.format(Double.parseDouble(Param.get("max_acceleration").toString())))));
        dri.setMileage(Math.abs(Double.parseDouble(df.format(Double.parseDouble(Param.get("mileage").toString())))));
        dri.setTime(Math.abs(Double.parseDouble(df.format(Double.parseDouble(Param.get("time").toString())))));
        dri.setStationarity(Math.abs(Double.parseDouble(df.format(Double.parseDouble(Param.get("stationarity").toString())))));
        dri.setCreateTime(new DateTime());

        drivedataMapper.updateById(dri);

        return 1;
    }

    @Override
    public int endDriveData(List<Long> tr_ids,Long userId) throws ParseException {

        Rank urank = rankService.selectByUserId(userId);

        Double milage = 0.0;
        Double time = 0.0;

        Double score = 0.0;
        Double stationarity = 0.0;

        Double maxspeed = urank.getMaxVel();
        Double maxacc = urank.getMaxAcc();
        Double maxnacc = urank.getMaxNAcc();
        Double Sacc = 0.0;

        Double morningtime = 0.0;
        Double afternoontime = 0.0;
        Double eveningtime = 0.0;

        SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");

        Date mbeginTime = df.parse("07:00:00");
        Date mendTime = df.parse("10:00:00");

        Date abeginTime = df.parse("15:00:00");
        Date aendTime = df.parse("20:00:00");

        Date ebeginTime1 = df.parse("22:00:00");
        Date eendTime1 = df.parse("23:59:59");

        Date ebeginTime2 = df.parse("00:00:00");
        Date eendTime2 = df.parse("04:00:00");


        for (Long id:tr_ids) {
            System.out.println(tr_ids);

            QueryWrapper<Drivedata> wrapper = new QueryWrapper<>();
            Drivedata now = drivedataMapper.selectOne(wrapper.eq("trail_id",id));

       //     milage +=now.getMileage();
       //     time +=now.getTime();
      //      score =now.getScore();
      //      stationarity += now.getStationarity();

      //      if (maxacc < now.getMaxAcceleration())maxacc = now.getMaxAcceleration();
      //      if (maxspeed < now.getMaxSpeed())maxspeed = now.getMaxSpeed();
      //      if (maxnacc < now.getMaxNacceleration())maxnacc = now.getMaxNacceleration();

     //       Sacc += now.getAverageAcceleration() * now.getTime();

            String notime = now.getCreateTime().toString().split(" ")[3];
            Timestamp timestamp = new Timestamp(now.getCreateTime().getTime());
            Date ntime = df.parse(notime);

            if(calculateUtil.belongCalendar(ntime, mbeginTime, mendTime)){
                morningtime += time;
            }
            if(calculateUtil.belongCalendar(ntime, abeginTime, aendTime)){
                afternoontime += time;
            }

            if(calculateUtil.belongCalendar(ntime, ebeginTime1, eendTime1) ||
                    calculateUtil.belongCalendar(ntime, ebeginTime2, eendTime2))
            {
                eveningtime += time;
            }

        }

   //     urank.setHisAcc((urank.getHisAcc() * urank.getAllTime() +Sacc*time) / (urank.getAllTime() + time));

   //     urank.setHisMileage(urank.getHisMileage() + milage);
   //     urank.setAllTime(urank.getAllTime() + time);
  //      urank.setMaxAcc(maxacc);
  //      urank.setMaxVel(maxspeed);
  //      urank.setMaxNAcc(maxnacc);
 //       urank.setStationarity(urank.getStationarity()+stationarity);


   //     urank.setHisVel(urank.getHisMileage()*3600/urank.getAllTime());

        int level = calculateUtil.CalculateLevel(urank.getHisMileage());
        urank.setLevel(level);
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        UserInfo userInfo =userInfoService.getById(urank.getUserId());
        //UserInfo userInfo = userInfoService.getUserInfoByUserId(urank.getUserId());
        userInfo.setRank(level);
        //userInfo.setDriveAge(urank.getHisMileage().intValue());
        userInfoService.updateInfo(userInfo);

        urank.setMorningTime(urank.getMorningTime()+morningtime);
        urank.setAfternoonTime(urank.getAfternoonTime()+afternoontime);
        urank.setMorningTime(urank.getEveningTime()+eveningtime);

        rankService.updateById(urank);

        return 1;
    }
}
